home *** CD-ROM | disk | FTP | other *** search
- /* 複素数演算マクロ集 */
- /* 2000.05.21 by M.Kamada */
-
- #include <math.h>
- #include <setjmp.h>
-
- /* 演算を続行できなくなったときのためにsetjmp(cjmpenv)で環境を準備しておくこと */
- jmp_buf cjmpenv;
-
- /* setjmp(cjmpenv)の返却値 */
- #define C_DIVIDE_BY_ZERO 1 /* 0で除算しようとした */
- #define C_ARG_ZERO 2 /* 0の角度を求めようとした */
-
- #ifndef __GNUC__
- #error "Sorry, GCC only"
- #endif
-
- #if __GNUC__==2
- #define complex __complex__
- #define Re(z) (__real__ (z))
- #define Im(z) (__imag__ (z))
- #else
- typedef struct {
- double re;
- double im;
- } complex;
- #define Re(z) ((z).re)
- #define Im(z) ((z).im)
- #endif
-
- #define tocomplex(r,i) \
- ({ \
- complex _z_; \
- Re(_z_) = (r); \
- Im(_z_) = (i); \
- _z_; \
- })
-
- #if __GNUC__==2
- #define C_1I (1.0i)
- #define C_2I (2.0i)
- #define C_3I (3.0i)
- #define C_4I (4.0i)
- #define C_5I (5.0i)
- #define C_6I (6.0i)
- #else
- #define C_1I tocomplex(0.0, 1.0)
- #define C_2I tocomplex(0.0, 2.0)
- #define C_3I tocomplex(0.0, 3.0)
- #define C_4I tocomplex(0.0, 4.0)
- #define C_5I tocomplex(0.0, 5.0)
- #define C_6I tocomplex(0.0, 6.0)
- #endif
-
- #define C_2PI (6.28318530717958647692528676656) /* 2*pi */
- #define C_PI (3.14159265358979323846264338328) /* pi */
- #define C_PI_2 (1.57079632679489661923132169164) /* pi/2 */
- #define C_PI_4 (0.78539816339744830961566084582) /* pi/4 */
- #define C_1_PI (0.318309886183790671537767526745) /* 1/pi */
- #define C_2_PI (0.63661977236758134307553505349) /* 2/pi */
- #define C_2_SQRTPI (1.12837916709551257389615890312) /* 2/sqrt(pi) */
- #define C_E (2.71828182845904523536028747135) /* e */
- #define C_LN10 (2.30258509299404568401799145468) /* ln(10) */
- #define C_LN2 (0.693147180559945309417232121458) /* ln(2) */
- #define C_LOG10E (0.434294481903251827651128918917) /* log10(e) */
- #define C_LOG2E (1.442695040888963407359924681) /* log2(e) */
- #define C_SQRT1_2 (0.707106781186547524400844362105) /* 1/sqrt(2) */
- #define C_SQRT2 (1.41421356237309504880168872421) /* sqrt(2) */
- #define C_SQRT3 (1.73205080756887729352744634151) /* sqrt(3) */
- #define C_SQRT5 (2.23606797749978969640917366873) /* sqrt(5) */
- #define C_SQRT6 (2.44948974278317809819728407471) /* sqrt(6) */
- #define C_SQRT7 (2.64575131106459059050161575364) /* sqrt(7) */
- #define C_SQRT8 (2.82842712474619009760337744842) /* sqrt(8) */
- #define C_SQRT10 (3.16227766016837933199889354443) /* sqrt(10) */
-
- /* xの実数部にsを加える */
- #if __GNUC__==2
- #define creadd(x,s) ((x)+(s))
- #else
- #define creadd(x,s) \
- ({ \
- complex _z_ = (x); \
- Re(_z_) += (s); \
- _z_; \
- })
- #endif
-
- /* xの虚数部にsを加える */
- #define cimadd(x,s) \
- ({ \
- complex _z_ = (x); \
- Im(_z_) += (s); \
- _z_; \
- })
-
- /* xの実数部からsを引く */
- #if __GNUC__==2
- #define cresub(x,s) ((x)-(s))
- #else
- #define cresub(x,s) \
- ({ \
- complex _z_ = (x); \
- Re(_z_) -= (s); \
- _z_; \
- })
- #endif
-
- /* xの虚数部からsを引く */
- #define cimsub(x,s) \
- ({ \
- complex _z_ = (x); \
- Im(_z_) -= (s); \
- _z_; \
- })
-
- /* xの実数s倍 */
- #if __GNUC__==2
- #define cremul(x,s) ((x)*(s))
- #else
- #define cremul(x,s) \
- ({ \
- complex _z_ = (x); \
- double _s_ = (s); \
- Re(_z_) *= _s_; \
- Im(_z_) *= _s_; \
- _z_; \
- })
- #endif
-
- /* xの虚数s*i倍 */
- #define cimmul(x,s) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- double _s_ = (s); \
- Re(_z_) = Im(_x_) * (-_s_); \
- Im(_z_) = Re(_x_) * _s_; \
- _z_; \
- })
-
- /* xのスカラーs倍 */
- #if __GNUC__==2
- #define cscal(x,s) ((x)*(s))
- #else
- #define cscal(x,s) \
- ({ \
- complex _z_ = (x); \
- double _s_ = (s); \
- Re(_z_) *= _s_; \
- Im(_z_) *= _s_; \
- _z_; \
- })
- #endif
-
- /* xの共役複素数 */
- #if __GNUC__==2
- #define conj(x) (~((__complex__)(x)))
- #else
- #define conj(x) \
- ({ \
- complex _z_ = (x); \
- Im(_z_) = -Im(_z_); \
- _z_; \
- })
- #endif
-
- /* xの絶対値の2乗 */
- #define cabs2(x) \
- ({ \
- complex _x_ = (x); \
- Re(_x_) * Re(_x_) + Im(_x_) * Im(_x_); \
- })
-
- /* xの絶対値 */
- #define cabs(x) \
- ({ \
- complex _x_ = (x); \
- sqrt(Re(_x_) * Re(_x_) + Im(_x_) * Im(_x_)); \
- })
-
- /* xの角度 */
- #define carg(x) \
- ({ \
- complex _x_ = (x); \
- if (Re(_x_) == 0.0 && Im(_x_) == 0.0) { \
- longjmp(cjmpenv, C_ARG_ZERO); \
- } \
- atan2(Im(_x_), Re(_x_)); \
- })
-
- /* x+y */
- #if __GNUC__==2
- #define cadd(x,y) ((x)+(y))
- #else
- #define cadd(x,y) \
- ({ \
- complex _z_ = (x); \
- complex _y_ = (y); \
- Re(_z_) += Re(_y_); \
- Im(_z_) += Im(_y_); \
- _z_; \
- })
- #endif
-
- /* x-y */
- #if __GNUC__==2
- #define csub(x,y) ((x)-(y))
- #else
- #define csub(x,y) \
- ({ \
- complex _z_ = (x); \
- complex _y_ = (y); \
- Re(_z_) -= Re(_y_); \
- Im(_z_) -= Im(_y_); \
- _z_; \
- })
- #endif
-
- /* x*y */
- #if __GNUC__==2
- #define cmul(x,y) ((x)*(y))
- #else
- #define cmul(x,y) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- complex _y_ = (y); \
- Re(_z_) = Re(_x_) * Re(_y_) - Im(_x_) * Im(_y_); \
- Im(_z_) = Re(_x_) * Im(_y_) + Im(_x_) * Re(_y_); \
- _z_; \
- })
- #endif
-
- /* x/y */
- #define cdiv(x,y) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- complex _y_ = (y); \
- double _r2_; \
- if ((_r2_ = cabs2(_y_)) == 0.0) { \
- longjmp(cjmpenv, C_DIVIDE_BY_ZERO); \
- } \
- Re(_z_) = (Re(_x_) * Re(_y_) + Im(_x_) * Im(_y_)) / _r2_; \
- Im(_z_) = (Im(_x_) * Re(_y_) - Re(_x_) * Im(_y_)) / _r2_; \
- _z_; \
- })
-
- /* xの2乗 (a+bi)^2=aa+2abi-bb */
- #define cpow2(x) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- Re(_z_) = Re(_x_) * Re(_x_) - Im(_x_) * Im(_x_); \
- Im(_z_) = (Re(_x_) * Im(_x_)) * 2.0; \
- _z_; \
- })
-
- /* xの3乗 (a+bi)^3=aaa+3aabi-3abb-bbbi */
- #define cpow3(x) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- double _aa_, _bb_; \
- _aa_ = Re(_x_) * Re(_x_); \
- _bb_ = Im(_x_) * Im(_x_); \
- Re(_z_) = Re(_x_) * (_aa_ - 3.0 * _bb_); /* aaa-3abb */ \
- Im(_z_) = Im(_x_) * (3.0 * _aa_ - _bb_); /* 3aab-bbb */ \
- _z_; \
- })
-
- /* xの4乗 (a+bi)^4=aaaa+4aaabi-6aabb-4abbbi+bbbb */
- #define cpow4(x) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- double _aa_, _bb_, _ab_; \
- _aa_ = Re(_x_) * Re(_x_); \
- _bb_ = Im(_x_) * Im(_x_); \
- _ab_ = Re(_x_) * Im(_x_); \
- Re(_z_) = _aa_ * (_aa_ - 6.0 * _bb_) + _bb_ * _bb_; /* aaaa-6aabb+bbbb */ \
- Im(_z_) = 4.0 * _ab_ * (_aa_ - _bb_); /* 4aaab-4abbb */ \
- _z_; \
- })
-
- /* xの5乗 (a+bi)^5=aaaaa+5aaaabi-10aaabb-10aabbbi+5abbbb+bbbbbi */
- #define cpow5(x) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- double _aa_, _bb_, _ab_, _aaa_, _bbb_; \
- _aa_ = Re(_x_) * Re(_x_); \
- _bb_ = Im(_x_) * Im(_x_); \
- _ab_ = Re(_x_) * Im(_x_); \
- _aaa_ = _aa_ * Re(_x_); \
- _bbb_ = _bb_ * Im(_x_); \
- Re(_z_) = _aaa_ * (_aa_ - 10.0 * _bb_) + 5.0 * _ab_ * _bbb_; /* aaaaa-10aaabb+5abbbb */ \
- Im(_z_) = 5.0 * _aaa_ * _ab_ + _bbb_ * (_bb_ - 10.0 * _aa_); /* 5aaaab+bbbbb-10aabbb */ \
- _z_; \
- })
-
- /* xの6乗 (a+bi)^6=aaaaaa+6aaaaabi-15aaaabb-20aaabbbi+15aabbbb+6abbbbbi-bbbbbb */
- #define cpow6(x) \
- ({ \
- complex _z_; \
- complex _x_ = (x); \
- double _aa_, _bb_, _ab_, _aaaa_, _bbbb_; \
- _aa_ = Re(_x_) * Re(_x_); \
- _bb_ = Im(_x_) * Im(_x_); \
- _ab_ = Re(_x_) * Im(_x_); \
- _aaaa_ = _aa_ * _aa_; \
- _bbbb_ = _bb_ * _bb_; \
- Re(_z_) = _aa_ * (_aa_ * (_aa_ - 15.0 * _bb_) + 15.0 * _bbbb_) - _bb_ * _bbbb_; /* aaaaaa-15aaaabb+15aabbbb-bbbbbb */ \
- Im(_z_) = _ab_ * (6.0 * (_aaaa_ + _bbbb_) - 20.0 * _aa_ * _bb_); /* 6aaaaab+6abbbbb-20aaabbb */ \
- _z_; \
- })
-
- /* xのe乗 */
- #define cpow(x,e) \
- ({ \
- complex _z_ = (x); \
- double _e_ = (e); \
- double _r_, _t_; \
- _r_ = pow(cabs(_z_), _e_); \
- _t_ = carg(_z_) * _e_; \
- Re(_z_) = _r_ * cos(_t_); \
- Im(_z_) = _r_ * sin(_t_); \
- _z_; \
- })
-
- /* xのm番目のn乗根 */
- #define crot(x,n,m) \
- ({ \
- complex _z_ = (x); \
- int _n_ = (n); \
- double _r_, _t_; \
- _r_ = pow(cabs(_z_), 1.0 / (double)_n_); \
- _t_ = carg(_z_) + C_2PI * (double)(m) / (double)_n_; \
- Re(_z_) = _r_ * cos(_t_); \
- Im(_z_) = _r_ * sin(_t_); \
- _z_; \
- })
-
- /* 距離の2乗 */
- #define cdist2(x,y) \
- ({ \
- complex _x_ = (x); \
- complex _y_ = (y); \
- double _r_ = Re(_x_) - Re(_y_); \
- double _i_ = Im(_x_) - Im(_y_); \
- _r_ * _r_ + _i_ * _i_; \
- })
-
- /* 距離 */
- #define cdist(x,y) \
- ({ \
- complex _x_ = (x); \
- complex _y_ = (y); \
- double _r_ = Re(_x_) - Re(_y_); \
- double _i_ = Im(_x_) - Im(_y_); \
- sqrt(_r_ * _r_ + _i_ * _i_); \
- })
-